package lime2;

//: containers/ListPerformance.java
// Demonstrates performance differences in Lists.
// {Args: 100 500} Small to keep build testing short
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

import lights.dracots.Field;
import lights.interfaces.ITuple;
import lights.interfaces.IValuedField;
import lime2.CountAndDispReactionListener;
import sagroup.util.*;

public class LTSPerformance {
	static String tsName = "testedTS";
	static Random rand = new Random();
	static int reps = 1000;
	static List<Test<LimeTupleSpace>> ltsTestsWithoutReaction = new ArrayList<Test<LimeTupleSpace>>();
	static List<Test<LimeTupleSpace>> ltsTestsWithReaction = new ArrayList<Test<LimeTupleSpace>>();
	static List<Test<LimeTSMgr>> ltsmTestsWithReaction = new ArrayList<Test<LimeTSMgr>>();;
	static {
		ltsTestsWithoutReaction.add(new Test<LimeTupleSpace>("out") {
			public int test(LimeTupleSpace list, TestParam tp) {
				int loops = tp.loops;
				int listSize = tp.size;
				TupleGenerator tg = new TupleGenerator();
				for (int i = 0; i < loops; i++) {
					// list.clear();
					for (int j = 0; j < listSize; j++) {
						list.out(tg.next());
					}
				}
				return loops * listSize;
			}
		});
		ltsTestsWithReaction.add(new Test<LimeTupleSpace>("out") {
			public int test(LimeTupleSpace list, TestParam tp) {
				int loops = tp.loops;
				int listSize = tp.size;
				TupleGenerator tg = new TupleGenerator();
				for (int i = 0; i < loops; i++) {
					// list.clear();
					for (int j = 0; j < listSize; j++) {
						list.out(tg.next());
					}
				}
				return loops * listSize;
			}
		});
		ltsmTestsWithReaction.add(new Test<LimeTSMgr>("out") {
			public int test(LimeTSMgr list, TestParam tp) {
				int loops = tp.loops;
				int listSize = tp.size;
				TupleGenerator tg = new TupleGenerator();
				for (int i = 0; i < loops; i++) {
					// list.clear();
					for (int j = 0; j < listSize; j++) {
						list.doWrite(new ITuple[] { tg.next() });
					}
				}
				return loops * listSize;
			}
		});
	}

	static class LTSTester extends Tester<LimeTupleSpace> {
		public LTSTester(LimeTupleSpace container,
				List<Test<LimeTupleSpace>> tests) {
			super(container, tests);
		}

		// Fill to the appropriate size before each test:
		@Override
		protected LimeTupleSpace initialize(int size) {
			TupleGenerator tg = new TupleGenerator();
			container.ing(Limes
					.createHUTemplate(Field.MATCH_ALL_FIELD.getValue()));
			for (int i = 0; i < size; i++) {
				container.out(tg.next());
			}
			// container.addAll(new CountingIntegerList(size));
			return container;
		}
	}

	static class LTSMTester extends Tester<LimeTSMgr> {
		public LTSMTester(LimeTSMgr container, List<Test<LimeTSMgr>> tests) {
			super(container, tests);
		}

		// Fill to the appropriate size before each test:
		@Override
		protected LimeTSMgr initialize(int size) {
			TupleGenerator tg = new TupleGenerator();
			// container.ing(Limes
			// .createHUTemplate(IValuedField.MULTI_FIELD_WILDCARD));
			// for (int i = 0; i < size; i++) {
			// container.out(tg.next());
			// }
			// container.addAll(new CountingIntegerList(size));
			return container;
		}
	}

	static class HasReactionLTSTester extends Tester<LimeTupleSpace> {
		public HasReactionLTSTester(LimeTupleSpace container,
				List<Test<LimeTupleSpace>> tests) {
			super(container, tests);
		}

		// Fill to the appropriate size before each test:
		@Override
		protected LimeTupleSpace initialize(int size) {
			TupleGenerator tg = new TupleGenerator();
			// container.ing(Limes.createHUTemplate(IValuedField.MULTI_FIELD_WILDCARD));
			for (int i = 0; i < size; i++) {
				CountAndDispReactionListener listener = new CountAndDispReactionListener();
				Reaction r = new Reaction(Reaction.ONCEPERTUPLE, Limes
						.createHHTemplate(tg.next()), listener);
				container.addStrongReaction(new Reaction[] { r });
			}
			// container.addAll(new CountingIntegerList(size));
			return container;
		}
	}

	private static int tsCounter = 0;

	public static void main(String[] args) {
		// , 100, 5000);
		// , 1000, 1000,
		// 10000, 200);
		if (args.length > 0)
			Tester.defaultParams = TestParam.array(args);
		Limes.startServer(1973, 8973);
		Logger logger = Logger.getLogger("");
		logger.setLevel(Level.OFF);
		Tester.defaultParams = TestParam.array(100, 10);
		LimeTSMgr.useReactionTree = true;
		testLTS();
		LimeTSMgr.useReactionTree = false;
		testLTS();
		// Tester<LimeTSMgr> ltsmTest;
		// ltsmTest = new LTSMTester(LimeTSMgr.creatLTSM("tsm1", (byte) 0),
		// ltsmTestsWithReaction);
		// ltsmTest.setHeadline("ltsmTestsWithReaction Tree");
		// ltsmTest.timedTest();

	}

	private static void testLTS() {
		Tester<LimeTupleSpace> ltsTest;
		ltsTest = new LTSTester(LimeTupleSpace.get("ts" + tsCounter++),
				ltsTestsWithoutReaction);
		ltsTest.setHeadline("ltsTestsWithoutReaction "
				+ (LimeTSMgr.useReactionTree ? "optimized" : "original"));
		ltsTest.timedTest();
		ltsTest = new HasReactionLTSTester(LimeTupleSpace.get("ts"
				+ tsCounter++), ltsTestsWithReaction);
		ltsTest.setHeadline("ltsTestsWithReaction "
				+ (LimeTSMgr.useReactionTree ? "optimized" : "original"));
		ltsTest.timedTest();
	}
}
